#include "Factorization.h"


Factorization::Factorization(void)
{
}


Factorization::~Factorization(void)
{
}

void initRandomMatrix(MatrixObject& m)
{
	for(int i = 0; i < m.ROWS; i++)
	{
		for(int j = 0; j < m.COLS; j++)
		{
			double temp = 0.5;
			
			m.setElement(i,j,temp);
		}
	}
}

void check1(MatrixObject& m)
{
	for(int i = 0; i < m.ROWS; i++)
	{
		for(int j = 0; j < m.COLS; j++)
		{
			if(m.getElement(i,j) >1) m.setElement(i,j,1);
		}
	}
}

void Factorization::NTF(Tensor X,MatrixObject& A,MatrixObject& B,MatrixObject& C,int times)
{
	initRandomMatrix(A);
	initRandomMatrix(B);
	initRandomMatrix(C);
	A.Output();
	B.Output();
	C.Output();
	Tensor W(X.x);
	for(int i = 0; i < X.x; i++)
	{
		for(int j = 0; j < X.x; j++)
		{
			for(int k=0; k < X.x; k++)
			{
				if(X.getElement(i,j,k) != 0) W.setElement(i,j,k,1); else W.setElement(i,j,k,0);
			}
		}
	}
	cout<<"Finish";
	for(int count = 0; count < times; count++)
	{
		MatrixObject temp1 = C.KRProduct(B);
		MatrixObject temp2 = X.matricification(1)*temp1;
		temp2 = A.elementwiseProduct(temp2);
		MatrixObject temp3 = A*temp1.T();
		temp3=W.matricification(1).elementwiseProduct(temp3);
		temp3 = temp3*temp1;
		A=temp2.elementwiseDivision(temp3);
		check1(A);
		cout<<"On the "<<count<<" Iteration A = ";
		A.Output();
		cout<<"\n";

		temp1 = C.KRProduct(A);
		temp2 = X.matricification(2)*temp1;
		temp2 = B.elementwiseProduct(temp2);
		//temp3 = B*temp1.T()*temp1;
		temp3 = B*temp1.T();
		temp3=W.matricification(2).elementwiseProduct(temp3);
		temp3 = temp3*temp1;
		
		B=temp2.elementwiseDivision(temp3);
		cout<<"On the "<<count<<" Iteration B = ";
				check1(B);
		B.Output();
		cout<<"\n";

		temp1 = B.KRProduct(A);
		temp2 = X.matricification(3)*temp1;
		temp2 = C.elementwiseProduct(temp2);
		//temp3 = C*temp1.T()*temp1;
		temp3 = C*temp1.T();
		temp3=W.matricification(3).elementwiseProduct(temp3);
		temp3 = temp3*temp1;
		C=temp2.elementwiseDivision(temp3);
		cout<<"On the "<<count<<" Iteration C = ";
				check1(C);
		C.Output();
		cout<<"\n";
	}
}